﻿using Newtonsoft.Json;
using System.Collections.Concurrent;
using System.Reflection;
using System.Text;

namespace Zhp.Cache
{
    internal static class ConvertHelper
    {
        /// <summary>
        /// json字符串序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T ToObject<T>(this string json)
        {
            if (!string.IsNullOrEmpty(json))
            {
                json = json.Replace("&nbsp;", "");
                return JsonConvert.DeserializeObject<T>(json);
            }
            else
            {
                return default;
            }
        }

        /// <summary>
        /// 对象转json字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static string ToJson<T>(this T obj)
        {
            if (obj != null)
            {
                return JsonConvert.SerializeObject(obj);
            }
            else
            {
                return String.Empty;
            }
        }

        /// <summary>
        /// 字节转字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string ByteToString(this byte[] bytes, Encoding encoding = null)
        {
            if (bytes == null)
            {
                return String.Empty;
            }
            else
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                return encoding.GetString(bytes);
            }
        }

        /// <summary>
        /// 字符串转字节
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static byte[] StringToBytes(this string str, Encoding encoding = null)
        {
            if (str == null)
            {
                str = String.Empty;
            }
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }
            return encoding.GetBytes(str);
        }

        /// <summary>
        /// 对象转字节
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static byte[] ObjectToBytes<T>(this T obj, Encoding encoding = null)
        {
            return obj.ToJson().StringToBytes();
        }

        /// <summary>
        /// 字节转对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bytes"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static T BytesToObject<T>(this byte[] bytes, Encoding encoding = null)
        {
            return bytes.ByteToString().ToObject<T>();
        }

        /// <summary>
        /// 字典转对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dict"></param>
        /// <returns></returns>
        public static T DictToObject<T>(this Dictionary<string, string> dict)
        {
            var obj = Activator.CreateInstance(typeof(T));

            foreach (var kvp in dict)
            {
                PropertyInfo propertyInfo = typeof(T).GetProperty(kvp.Key);

                if (propertyInfo != null && propertyInfo.CanWrite)
                {
                    var json = JsonConvert.DeserializeObject(kvp.Value, propertyInfo.PropertyType);
                    propertyInfo.SetValue(obj, json);
                }
            }

            return (T)obj;
        }

        /// <summary>
        /// 字典转对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dict"></param>
        /// <returns></returns>
        public static T ConDictToObject<T>(this ConcurrentDictionary<string, string> dict)
        {
            var obj = Activator.CreateInstance(typeof(T));

            foreach (var kvp in dict)
            {
                PropertyInfo propertyInfo = typeof(T).GetProperty(kvp.Key);

                if (propertyInfo != null && propertyInfo.CanWrite)
                {
                    var json = JsonConvert.DeserializeObject(kvp.Value, propertyInfo.PropertyType);
                    propertyInfo.SetValue(obj, json);
                }
            }

            return (T)obj;
        }

        /// <summary>
        /// 对象转字典
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Dictionary<string, object> ObjectToDict<T>(this T obj)
        {
            return obj.ToJson().ToObject<Dictionary<string, object>>();
        }

        /// <summary>
        /// 对象转字典
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static ConcurrentDictionary<string, string> ObjectToConDict<T>(this T obj)
        {
            var dict = new ConcurrentDictionary<string, string>();
            var props = obj.GetType().GetProperties();
            foreach (var item in props)
            {
                dict[item.Name] = item.GetValue(obj).ToJson();
            }
            return dict;
        }
    }
}
